package cn.sfrog.project.biz.admin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.sfrog.common.constant.Constants;
import cn.sfrog.common.utils.SecurityUtils;
import cn.sfrog.common.utils.StringUtils;
import cn.sfrog.project.biz.admin.domain.BizService;
import cn.sfrog.project.biz.admin.domain.BizServiceUser;
import cn.sfrog.project.biz.admin.domain.vo.BizServiceFormVO;
import cn.sfrog.project.biz.admin.domain.vo.BizServiceQueryVO;
import cn.sfrog.project.biz.admin.domain.vo.BizServiceVO;
import cn.sfrog.project.biz.admin.mapper.BizServiceMapper;
import cn.sfrog.project.biz.admin.service.IBizComboService;
import cn.sfrog.project.biz.admin.service.IBizServiceOrderEvaluationService;
import cn.sfrog.project.biz.admin.service.IBizServiceService;
import cn.sfrog.project.biz.web.vo.combo.AppChangeStatusVO;
import cn.sfrog.project.biz.web.vo.order.AppOrderEvaluationVO;
import cn.sfrog.project.biz.web.vo.service.AppServiceDetailQueryVO;
import cn.sfrog.project.biz.web.vo.service.AppServiceDetailResultVO;
import cn.sfrog.system.domain.vo.BizStatusChangeVO;
import cn.sfrog.system.domain.vo.app.AppServiceQueryVO;
import cn.sfrog.system.domain.vo.app.AppServiceResultVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 服务Service业务层处理
 */
@Service
public class BizServiceServiceImpl extends ServiceImpl<BizServiceMapper, BizService> implements IBizServiceService {
    @Resource
    private BizServiceMapper bizServiceMapper;
    @Autowired
    private IBizComboService bizComboService;
    @Autowired
    private IBizServiceOrderEvaluationService bizServiceOrderEvaluationService;

    /**
     * 查询服务
     *
     * @param id 服务主键
     * @return 服务
     */
    @Override
    public BizServiceVO selectBizServiceById(Long id) {
        BizServiceVO bizServiceVO = bizServiceMapper.selectBizServiceById(id);
        LambdaQueryWrapper<BizServiceUser> lambdaQueryWrapper = new LambdaQueryWrapper<BizServiceUser>()
                .eq(BizServiceUser::getProductId,id)
                .eq(BizServiceUser::getUserId,SecurityUtils.getLoginUser().getUser().getUserId())
                .eq(BizServiceUser::getType,Constants.TYPE_SERVICE);
        BizServiceUser serviceUser = BizServiceUser.DAO.selectOne(lambdaQueryWrapper);
        if(StringUtils.isNotNull(serviceUser)){
            bizServiceVO.setStatus(serviceUser.getStatus());
        }
        return bizServiceVO;
    }

    /**
     * 查询服务列表
     *
     * @param query 服务
     * @return 服务
     */
    @Override
    public List<BizServiceVO> selectBizServiceList(BizServiceQueryVO query) {
        return bizServiceMapper.selectBizServiceList(query);
    }

    /**
     * 新增服务
     *
     * @param form 服务
     * @return 结果
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean insertBizService(BizServiceFormVO form) {
        BizService bizService = new BizService();
        BeanUtils.copyProperties(form, bizService);
        if(form.getHospitalIds() !=null){
           bizService.setHospitalCount(form.getHospitalIds().length);
           bizService.setHospitalIds(StringUtils.join(form.getHospitalIds(),","));
        }
        bizService.setCreateTime(new Date());
        bizService.setCreateBy(SecurityUtils.getUsername());
        bizService.setUpdateTime(new Date());
        bizService.setUpdateBy(SecurityUtils.getUsername());
        return bizService.insert();
    }

    /**
     * 修改服务
     *
     * @param form 服务
     * @return 结果
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean updateBizService(BizServiceFormVO form) {
        BizService bizService = new BizService();
        BeanUtils.copyProperties(form, bizService);
        if(form.getHospitalIds() !=null){
            bizService.setHospitalCount(form.getHospitalIds().length);
            bizService.setHospitalIds(StringUtils.join(form.getHospitalIds(),","));
        };
        bizService.setUpdateTime(new Date());
        bizService.setUpdateBy(SecurityUtils.getUsername());
        return bizService.updateById();
    }

    /**
     * 批量删除服务
     *
     * @param ids 需要删除的服务主键
     * @return 结果
     */
    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean deleteBizServiceByIds(Long[] ids) {
            return BizService.DAO.delete(Wrappers.lambdaQuery(BizService.class).in(BizService::getId, (Object[]) ids));
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean changeStatus(BizStatusChangeVO vo) {
        return BizService.DAO.update(Wrappers.lambdaUpdate(BizService.class).in(BizService::getId, (Object[]) vo.getIds()).set(BizService::getStatus, vo.getStatus()));
    }

    @Override
    public List<AppServiceResultVO> selectAppServiceList(AppServiceQueryVO serviceQueryVO) {
        List<AppServiceResultVO> resultVOList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(serviceQueryVO.getIds())){
            // TODO: 2022/9/16 服务的预约数量怎么计算
            resultVOList = bizServiceMapper.selectAppServiceList(serviceQueryVO);
        }

        return resultVOList;
    }

    @Override
    public List<AppServiceResultVO> selectAppServiceList2(AppServiceQueryVO serviceQueryVO) {
        List<AppServiceResultVO> resultVOList = new ArrayList<>();
        resultVOList = bizServiceMapper.selectAppServiceList(serviceQueryVO);
        return resultVOList;
    }

    @Override
    public AppServiceDetailResultVO selectAppServiceDetail(AppServiceDetailQueryVO queryVO) {
        AppServiceDetailResultVO resultVO = new AppServiceDetailResultVO();
        if(Constants.TYPE_SERVICE.equals(queryVO.getType())){
            //服务
            resultVO =  bizServiceMapper.selectAppServiceDetail(queryVO.getId());
        }else if(Constants.TYPE_COMBO.equals(queryVO.getType())) {
            //套餐
            resultVO = bizComboService.selectAppComboDetail(queryVO.getId());
        }
        //查询套餐服务的好评率 1.查询这个服务的所有订单
        List<AppOrderEvaluationVO> evaluationVOList = bizServiceOrderEvaluationService.selectAllEvaluationOrder(queryVO.getType(),queryVO.getId(),null);
        if(CollectionUtil.isEmpty(evaluationVOList)){
            resultVO.setFavorableRate(BigDecimal.ZERO);
        }else {
            //将所有订单中好评的过滤出来 评分 > 3 为好评
            List<AppOrderEvaluationVO> goodList = evaluationVOList.stream().filter(x -> x.getScore() > 3).collect(Collectors.toList());
            if(CollectionUtil.isEmpty(goodList)){
                resultVO.setFavorableRate(BigDecimal.ZERO);
            }else {
                BigDecimal goodCount = BigDecimal.valueOf(goodList.size());
                BigDecimal allCount = BigDecimal.valueOf(evaluationVOList.size());
                resultVO.setFavorableRate((goodCount.divide(allCount,2,BigDecimal.ROUND_CEILING).multiply(BigDecimal.valueOf(100))).setScale(1,BigDecimal.ROUND_DOWN));
            }

        }

        return resultVO;
    }

    @Override
    public Boolean updateStatusByApp(AppChangeStatusVO vo) {
        LambdaUpdateWrapper<BizServiceUser> updateWrapper = new LambdaUpdateWrapper<BizServiceUser>()
                .eq(BizServiceUser::getType, Constants.TYPE_SERVICE)
                .eq(BizServiceUser::getProductId, vo.getId())
                .eq(BizServiceUser::getUserId, SecurityUtils.getLoginUser().getUser().getUserId())
                .set(BizServiceUser::getStatus,vo.getStatus());
        return BizServiceUser.DAO.update(updateWrapper);
    }

    @Override
    public List<BizServiceVO> getServiceAllList() {
        List<BizServiceVO> serviceAllList = bizServiceMapper.getServiceAllList();
        return serviceAllList;
    }
}
